#!/usr/bin/env python
#coding=UTF-8
'''
Created on 2010-11-4

@author: zarra
'''
from numpy import pi
from numpy import  mat,sin,cos,abs
import cv
from common import Question
    

class Q2(Question):
    def __init__(self,image,m='show'):
        super(self.__class__,self).__init__('Q2',image,m)
                
    def safe_read(self,x,y):
        hw=self.image.width/2
        hh=self.image.height/2
        if abs(x)>hw or abs(y)>hh:
            return 0
        x=x if abs(x)<hw else hw-1
        y=y if abs(y)<hh else hh-1
        return self.image[y+hh,x+hw] 
    @staticmethod
    def find_nei(a,b):
        x=int(a)
        y=int(b)
        r =[ (a,b),(x,y),(x+1,y),(x,y+1),(x+1,y+1)]
        if r == ():
            print a,b
        return r

    def transform(self,dst,m,method):
        width,height = dst.width,dst.height
    
        for y in range(height):
            for x in range(width):
                px=x-width/2
                py=y-height/2
                a=m[0,0]*px+m[0,1]*py+m[0,2]
                b=m[1,0]*px+m[1,1]*py+m[1,2]
                point = Q2.find_nei(a, b)
                if point == None:
                    print px,py
                else:
                    dst[y,x] = method(point)
        return dst
            

             
    def nearest(self,args):
        x,y=args[0]
        x=int(round(x))
        y=int(round(y))
        return self.safe_read(x, y)    

    def bilinear(self,args):
        x,y=args[0]
        f_00=self.safe_read(*args[1])
        f_10=self.safe_read(*args[2])
        f_01=self.safe_read(*args[3])
        f_11=self.safe_read(*args[4])  
        
        d=f_00
        a=f_10-d
        b=f_01-d
        c=f_11-a-b-d
        x=abs(x-int(x))
        y=abs(y-int(y))
        f=a*x+b*y+c*x*y+d
        return f
         
    def transform_c(self,m,title):
        image = self.image
        out = cv.CreateImage((image.width,image.height), cv.IPL_DEPTH_8U, 1)
        self.transform(out, m,self.nearest)
        self.display(out, title+'_nearest') 
        out = cv.CreateImage((image.width,image.height), cv.IPL_DEPTH_8U, 1)
        self.transform(out, m,self.bilinear)
        self.display(out, title+'_bilinear') 
           
    def action(self):
        
        d= pi/2
        
        m1=mat([
          [1,0,50],
          [0,1,20],
          [0,0,1],
          ],float)
        
        m2=mat([
          [.5,0,0],
          [0,.5,0],
          [0,0,1],
          ],float)
        
        m3=mat([
          [cos(d),-sin(d),0],
          [sin(d),cos(d),0],
          [0,0,1],
          ],float)
    
        image = self.image
        self.display(image, 'Image')
        
        self.transform_c(m1, 'translation')
        self.transform_c(m2, 'scale')
        self.transform_c(m3, 'rotation')
        
if __name__ == '__main__':
    q=Q2('fig3.jpg','save')
    q()